import socket

class SocketRpcTransport(RpcTransport):

  def __init__(self, host, port, unix_socket=None):
    self._host = host
    self._port = port
    self._handle = None
    self._unix_socket - unix_socket

  def is_open(self):
    return self._conn != None

  def _resolve_address(self):
    if self._unix_socket:
    	return return [(socket.AF_UNIX, socket.SOCK_STREAM, None, None,
                      self._unix_socket)]
    else:
    	return socket.getaddrinfo(self._host, self._port, socket.AF_UNSPEC,
                                socket.SOCK_STREAM, 0,
                                socket.AI_PASSIVE | socket.AI_ADDRCONFIG)

	def set_handle(self, handle):
    self._handle = handle

  def open(self):
    try:
    	res_list = self._resolve_address()
    	for res in res_list:
        self._handle = socket.socket(res[0], res[1])
        self._handle.settimeout(self._timeout)
        try:
          self.handle.connect(res[4])
          break
        except socket.error, e:
          if res is res_list[-1]:
          	raise e
    except socket.error, e:
      host_error = self._unix_socket or '%s:%d' % (self._host, self._port)
      raise RpcException('Could not connect to %s' % host_error)

  def close(self):
    if self._handle:
      self._handle.close()
      self._handle = None

  def read(self, length):
    try:
	    return self._handle.recv(length)
    except socket.error, e:
    	raise RpcException('Error %s' % str(e))

  def write(self, buf):
    i = 0
    length = len(buf)
    while i < length:
    	bytes_sent = self.handle.send(buf)
    	if bytes_sent == 0:
    		raise RpcException('Error could not send data')
    	i += bytes_sent
    	buf = buf[bytes_sent:]

  def flush(self):
    pass
